// Fill out your copyright notice in the Description page of Project Settings.

#include "TextFileManage.h"
#include "Misc/FileHelper.h"
#include "HAL/PlatformFilemanager.h"
#include "Paths.h"

#include "Windows/WindowsSystemIncludes.h"


using namespace Windows;

#define CONST const
#define CALLBACK __stdcall
#ifdef FALSE
#undef FALSE
#endif
#define FALSE 0

#ifdef TRUE
#undef TRUE
#endif
#define TRUE  1
typedef wchar_t WCHAR;
typedef const char* LPCSTR;
typedef CONST WCHAR *LPCWSTR;
typedef WCHAR *LPWSTR;
typedef LONG_PTR LPARAM;
typedef UINT_PTR WPARAM;
#define far
#define near
#define FAR                 far
#define NEAR                near

#ifdef _WIN64
typedef INT_PTR(FAR WINAPI *FARPROC)();
typedef INT_PTR(NEAR WINAPI *NEARPROC)();
typedef INT_PTR(WINAPI *PROC)();
#else
typedef int (FAR WINAPI *FARPROC)();
typedef int (NEAR WINAPI *NEARPROC)();
typedef int (WINAPI *PROC)();
#endif  // _WIN64



// extern "C" __declspec(dllimport) HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName);
// extern "C" __declspec(dllimport) FARPROC WINAPI GetProcAddress(HMODULE hModule, LPCSTR lpProcName);

// const HMODULE H_comdlg32 = [] { return LoadLibraryW(L"comdlg32.dll"); }();
// const HMODULE H_user32 = [] {return LoadLibraryW(L"user32.dll"); }();


typedef UINT_PTR(CALLBACK *LPOFNHOOKPROC) (HWND, UINT, WPARAM, LPARAM);
typedef struct tagOFNW {
	DWORD        lStructSize;
	HWND         hwndOwner;
	HINSTANCE    hInstance;
	LPCWSTR      lpstrFilter;
	LPWSTR       lpstrCustomFilter;
	DWORD        nMaxCustFilter;
	DWORD        nFilterIndex;
	LPWSTR       lpstrFile;
	DWORD        nMaxFile;
	LPWSTR       lpstrFileTitle;
	DWORD        nMaxFileTitle;
	LPCWSTR      lpstrInitialDir;
	LPCWSTR      lpstrTitle;
	DWORD        Flags;
	WORD         nFileOffset;
	WORD         nFileExtension;
	LPCWSTR      lpstrDefExt;
	LPARAM       lCustData;
	LPOFNHOOKPROC lpfnHook;
	LPCWSTR      lpTemplateName;
#ifdef _MAC
	LPEDITMENU   lpEditInfo;
	LPCSTR       lpstrPrompt;
#endif
#if (_WIN32_WINNT >= 0x0500)
	void *        pvReserved;
	DWORD        dwReserved;
	DWORD        FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
} OPENFILENAMEW, *LPOPENFILENAMEW;


extern "C" BOOL WINAPI GetOpenFileNameW(LPOPENFILENAMEW Arg1);
extern "C" HWND WINAPI GetActiveWindow();
// BOOL(WINAPI *const H_GetOpenFileNameW)(LPOPENFILENAMEW Arg1) = [] { return (BOOL(WINAPI *)(LPOPENFILENAMEW)) GetProcAddress(H_comdlg32, "GetOpenFileNameW"); }();
// HWND(WINAPI *const H_GetActiveWindow) () = [] {return (HWND(WINAPI *)()) GetProcAddress(H_user32, "GetActiveWindow"); }();

#define OFN_PATHMUSTEXIST            0x00000800
#define OFN_FILEMUSTEXIST            0x00001000
#define OFN_EXPLORER                 0x00080000


bool UTextFileManage::SaveArrayText(FString SaveDirctory, FString FileName, TArray<FString> SaveText, bool AllowOverWriting = false)
{
	// set complete file path
	SaveDirctory += "\\";
	SaveDirctory += FileName;

	if (!AllowOverWriting)
	{
		if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*SaveDirctory))
		{
			return false;
		}
	}

	FString FinalString = "";
	for (FString & each:SaveText)
	{
		FinalString += each;
		FinalString += LINE_TERMINATOR;
	}

	return FFileHelper::SaveStringToFile(FinalString,*SaveDirctory);
}

bool UTextFileManage::LoadText(FString FileNameA, FString & SaveTextA)
{
	return FFileHelper::LoadFileToString(SaveTextA, *(FPaths::ProjectDir() + FileNameA));
}

bool UTextFileManage::SaveText(FString SaveTextB, FString FileNameB)
{
	return FFileHelper::SaveStringToFile(SaveTextB, *(FPaths::ProjectDir() + FileNameB));
}

void UTextFileManage::LoadCSVFile(FString LoadDirctory, FString FileName, FString & FileContent)
{
	LoadDirctory += "\\";
	LoadDirctory += FileName;
	if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*LoadDirctory))
	{
		FFileHelper::LoadFileToString(FileContent, *LoadDirctory);
	}
}

FString UTextFileManage::SelectFile()
{
	// HWND WINAPI GetActiveWindow(void);

	OPENFILENAMEW ofn;       // common dialog box structure
	WCHAR szFile[260] = { 0 };       // if using TCHAR macros

	// Initialize OPENFILENAME
	memset(&ofn, 0, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = GetActiveWindow();
	ofn.lpstrFile = szFile;
	ofn.nMaxFile = sizeof(szFile) / sizeof(szFile[0]);
	ofn.lpstrFilter = L"Data File\0*.DAT\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	ofn.lpstrInitialDir = NULL;
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;

	if (GetOpenFileNameW(&ofn) == TRUE)
	{
		return FString(ofn.lpstrFile);
	}
	else {
		return "";
	}
}
